package com.isky.visual.proj.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.isky.visual.constant.CommonConstant;
import com.isky.visual.exception.GlobalException;
import com.isky.visual.interceptor.PlatformUserManager;
import com.isky.visual.proj.config.PanelGroupTypeEnum;
import com.isky.visual.proj.entity.PanelGroup;
import com.isky.visual.proj.entity.PanelGroupUser;
import com.isky.visual.proj.entity.vo.*;
import com.isky.visual.proj.mapper.PanelGroupMapper;
import com.isky.visual.proj.mapper.PanelGroupUserMapper;
import com.isky.visual.proj.service.IPanelGroupService;
import com.isky.visual.proj.service.IProjectService;
import com.isky.visual.result.CodeMsg;
import com.isky.visual.user.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 项目分组表 服务实现类
 * </p>
 *
 * @author wudl
 * @since 2020-04-28
 */
@Service
public class PanelGroupServiceImpl extends ServiceImpl<PanelGroupMapper, PanelGroup> implements IPanelGroupService {

    @Autowired
    PanelGroupMapper panelGroupMapper;

    @Autowired
    PanelGroupUserMapper panelGroupUserMapper;

    @Autowired
    TransactionTemplate transactionTemplate;

    @Autowired
    IProjectService projectService;

    @Value("${project.panel.defaultRootName}")
    private String defaultRootName;

    @Override
    public List<ProjectVisualVO> getAllPublishVisual(int type) {
        User user = PlatformUserManager.getUser();
        List<ProjectVisualVO> allPublishVisual = panelGroupMapper.getAllPublishVisual(user.getId(), type);
        if (allPublishVisual.size() < 0) {
            throw new GlobalException(CodeMsg.DB_GET_DATA_ERROR);
        }
        return allPublishVisual;
    }

    @Override
    public List<ProjectVisualVO> getGroupDashboard(int type) {

        User user = PlatformUserManager.getUser();
        List<PanelGroup> projectList = panelGroupMapper.getGroupDashboard(user.getId(), type);
        Stream<PanelGroup> stream = projectList.stream();
        Map<Long, List<PanelGroup>> map = stream.collect(Collectors.groupingBy(PanelGroup::getParentId));

        List<ProjectVisualVO> result = parseTree(CommonConstant.PANEL_ROOT_ID, map);

        return result;
    }

    @Override
    public boolean create(PanelGroupParam panelGroupParam) {
        User user = PlatformUserManager.getUser();
        Long parentId = panelGroupParam.getParentId();
        if (parentId == null || Objects.equals(parentId, CommonConstant.PANEL_ROOT_ID)) {
            //如果parentId 为空，则找这个用户的对应类型的根节点
            PanelGroup panelGroup = panelGroupMapper.selectRoot(panelGroupParam.getGroupType(), user.getId());
            panelGroupParam.setParentId(panelGroup.getGroupId());
        }
        synchronized (user){
            List<PanelGroup> panelGroups = panelGroupMapper.selectBYNameAndUserId(user.getId(), panelGroupParam.getGroupName(), panelGroupParam.getGroupType());
            if(panelGroups != null && !panelGroups.isEmpty()){
                throw new GlobalException(CodeMsg.PROJECT_GROUP_EXISTS);
            }
        }

        Boolean execute = transactionTemplate.execute((status) -> {
            PanelGroup panelGroup = new PanelGroup();
            panelGroup.setValid(true);
            panelGroup.setGroupName(panelGroupParam.getGroupName());
            panelGroup.setGroupType(panelGroupParam.getGroupType());
            panelGroup.setParentId(panelGroupParam.getParentId());
            panelGroupMapper.insert(panelGroup);
            panelGroup.setGroupId(panelGroup.getId());
            panelGroupMapper.updateById(panelGroup);
            panelGroupParam.setGroupId(panelGroup.getId());

            PanelGroupUser panelGroupUser = new PanelGroupUser();
            panelGroupUser.setGroupId(panelGroup.getGroupId());
            panelGroupUser.setUserId(user.getId());
            panelGroupUser.setValid(true);
            panelGroupUserMapper.insert(panelGroupUser);
            return true;
        });
        ProjectMoveParam moveParam = new ProjectMoveParam();
        moveParam.setGroupId(panelGroupParam.getGroupId());
        moveParam.setProjectIds(panelGroupParam.getProjectIds());
        projectService.move(moveParam);
        return execute;
    }

    @Override
    public boolean rename(PanelGroupParam panelGroupParam) {

        Long groupId = panelGroupParam.getGroupId();
        PanelGroup panelGroup = panelGroupMapper.selectByGroupId(groupId);
        if (panelGroup == null) {
            return false;
        }

        User user = PlatformUserManager.getUser();
        List<PanelGroup> panelGroups = panelGroupMapper.selectBYNameAndUserId(user.getId(), panelGroupParam.getGroupName(), panelGroup.getGroupType());
        if(panelGroups != null && !panelGroups.isEmpty()){
            throw new GlobalException(CodeMsg.PROJECT_GROUP_EXISTS);
        }
       
        panelGroup.setGroupName(panelGroupParam.getGroupName());
        int update = panelGroupMapper.updateById(panelGroup);

        return update > 0 ? true : false;
    }

    @Override
    public boolean move(PanelGroupMoveParam panelGroupMoveParam) {
        User user = PlatformUserManager.getUser();
        Long parentId = panelGroupMoveParam.getParentId();
        if (parentId == null || Objects.equals(parentId, CommonConstant.PANEL_ROOT_ID)) {
            //如果parentId 为空，则找这个用户的对应类型的根节点
            PanelGroup panelGroup = panelGroupMapper.selectRoot(panelGroupMoveParam.getGroupType(), user.getId());
            panelGroupMoveParam.setParentId(panelGroup.getGroupId());
        }

        Boolean execute = transactionTemplate.execute((status) -> {
            Long[] groupIds = panelGroupMoveParam.getGroupIds();
            for (Long groupId : groupIds) {
                PanelGroup panelGroup = panelGroupMapper.selectByGroupId(groupId);
                if (panelGroup == null) {
                    continue;
                }

                panelGroup.setParentId(panelGroupMoveParam.getParentId());
                panelGroupMapper.updateById(panelGroup);
            }

            return true;
        });

        return execute;
    }

    @Override
    public boolean delete(PanelGroupDeleteParam panelGroupDeleteParam) {

        Boolean execute = transactionTemplate.execute((status) -> {
            Long[] groupIds = panelGroupDeleteParam.getId();
            for (Long groupId : groupIds) {
                PanelGroup panelGroup = panelGroupMapper.selectByGroupId(groupId);
                if (panelGroup == null) {
                    continue;
                }

                panelGroup.setValid(false);
                panelGroupMapper.updateById(panelGroup);
            }

            return true;
        });

        return execute;
    }

    @Override
    public boolean addRootByUserId(Long userId) {
        Boolean execute = transactionTemplate.execute((status) -> {
            PanelGroup pgPersonShare = panelGroupMapper.selectRoot(PanelGroupTypeEnum.PERSON_SHARE.getType(), userId);
            if (pgPersonShare == null) {
                pgPersonShare = new PanelGroup();
                pgPersonShare.setValid(true);
                pgPersonShare.setGroupName(defaultRootName);
                pgPersonShare.setGroupType(PanelGroupTypeEnum.PERSON_SHARE.getType());
                pgPersonShare.setParentId(CommonConstant.PANEL_ROOT_ID);
                panelGroupMapper.insert(pgPersonShare);
                pgPersonShare.setGroupId(pgPersonShare.getId());
                panelGroupMapper.updateById(pgPersonShare);

                PanelGroupUser panelGroupUser = new PanelGroupUser();
                panelGroupUser.setValid(true);
                panelGroupUser.setGroupId(pgPersonShare.getGroupId());
                panelGroupUser.setUserId(userId);
                panelGroupUserMapper.insert(panelGroupUser);
            }

            PanelGroup pgPerson = panelGroupMapper.selectRoot(PanelGroupTypeEnum.PERSON.getType(), userId);
            if (pgPerson == null) {
                pgPerson = new PanelGroup();
                pgPerson.setValid(true);
                pgPerson.setGroupName(defaultRootName);
                pgPerson.setGroupType(PanelGroupTypeEnum.PERSON.getType());
                pgPerson.setParentId(CommonConstant.PANEL_ROOT_ID);
                panelGroupMapper.insert(pgPerson);
                pgPerson.setGroupId(pgPerson.getId());
                panelGroupMapper.updateById(pgPerson);

                PanelGroupUser panelGroupUser = new PanelGroupUser();
                panelGroupUser.setValid(true);
                panelGroupUser.setGroupId(pgPerson.getGroupId());
                panelGroupUser.setUserId(userId);
                panelGroupUserMapper.insert(panelGroupUser);
            }

            return true;
        });

        return execute;
    }


    private List<ProjectVisualVO> parseTree(Long parentId, Map<Long, List<PanelGroup>> map) {

        List<ProjectVisualVO> list = null;
        if (map.containsKey(parentId)) {
            list = new ArrayList<>();
            List<PanelGroup> projectGroups = map.get(parentId);
            if (projectGroups != null && !projectGroups.isEmpty()) {
                for (PanelGroup projectGroup : projectGroups) {
                    ProjectVisualVO vo = new ProjectVisualVO();
                    vo.setId(projectGroup.getGroupId());
                    vo.setProjectName(projectGroup.getGroupName());
                    list.add(vo);

                    vo.setChilden(parseTree(vo.getId(), map));
                }
            }
        }
        return list;
    }

}
